package com.haiyuancloud.base.id.service;


import com.haiyuancloud.base.id.entity.SeqRegistryBusiEntity;
import com.haiyuancloud.base.id.mapper.SeqRegistryBusiMapper;
import com.haiyuancloud.common.redis.service.CaffeineCacheService;
import com.haiyuancloud.util.ObjectUtil;
import com.power4j.kit.seq.core.SeqFormatter;
import com.power4j.kit.seq.core.Sequence;
import com.power4j.kit.seq.ext.SequenceRegistry;
import com.power4j.kit.seq.persistent.Partitions;
import com.power4j.kit.seq.persistent.SeqHolder;
import com.power4j.kit.seq.persistent.SeqSynchronizer;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.function.Supplier;

@Service("com.haiyuancloud.base.id.service.Power4jNoService")
@RequiredArgsConstructor
public class Power4jNoService {

//    private final Supplier<String> partitionFunc = Partitions.DAILY;

    //    private final static SeqFormatter MY_FORMATTER = (seqName, partition, value) -> String.format("%s-%s-%04d", seqName,
//            partition, value);

    private final SeqSynchronizer seqSynchronizer;

    private final CaffeineCacheService caffeineCacheService;

    private final SeqRegistryBusiMapper seqRegistryBusiMapper;

    private final SequenceRegistry<Long, Sequence<Long>> sequenceRegistry;

    public String getForName(String name) {
        String no = sequenceRegistry.getOrRegister(name, this::createSequence).nextStr();
        SeqRegistryBusiEntity seqRegistryBusiEntity  = getSeqRegistryBusiEntity( name);
        if(ObjectUtil.isNotNull(seqRegistryBusiEntity)){
            return no.replace(name,seqRegistryBusiEntity.getVIEW_SEQ_NAME());
        }else{
            return no;
        }
    }

    private Sequence<Long> createSequence(String name) {
        Supplier<String>  partitionFunc = Partitions.DAILY;
        Long  initValue = 1L;
        Integer  poolSize = 100;
        Integer  seqLen = 5;
        Integer  func = 1;
        String beforeTag = "";
        String afterTag = "";

        SeqRegistryBusiEntity seqRegistryBusiEntity  = getSeqRegistryBusiEntity( name);
        if(ObjectUtil.isNotNull(seqRegistryBusiEntity)){
            initValue = ObjectUtil.toLong(seqRegistryBusiEntity.getI_FUNC_INIT(),initValue);
            poolSize = ObjectUtil.toInteger(seqRegistryBusiEntity.getBUSI_POOL_SIZE(),poolSize);
            seqLen = ObjectUtil.toInteger(seqRegistryBusiEntity.getI_FUNC_LEN(),seqLen);
            func = ObjectUtil.toInteger(seqRegistryBusiEntity.getI_FUNC(),func);
            if(func== 1) {
                partitionFunc = Partitions.DAILY;
            }else if(func == 2){
                partitionFunc = Partitions.MONTHLY;
            }else if(func == 3){
                partitionFunc = Partitions.ANNUALLY;
            }
            beforeTag = ObjectUtil.toString(seqRegistryBusiEntity.getSEQ_BEFORE_TAG());
            afterTag = ObjectUtil.toString(seqRegistryBusiEntity.getSEQ_AFTER_TAG());
        }
        String format = "%s"+beforeTag+"%s"+afterTag+"%0"+seqLen+"d";
        SeqFormatter MY_FORMATTER = (seqName, partition, value) -> String.format(format, seqName, partition, value);
        return new SeqHolder(seqSynchronizer, name, partitionFunc, initValue, poolSize, MY_FORMATTER);
    }


    private SeqRegistryBusiEntity getSeqRegistryBusiEntity(String name){
        SeqRegistryBusiEntity seqRegistryBusiEntity  = null;
        Object seqRegistryBusiValue = caffeineCacheService.get(name);
        if(ObjectUtil.isNull(seqRegistryBusiValue)){
            seqRegistryBusiEntity  = seqRegistryBusiMapper.getSeqRegistryBusi(name);
            if(ObjectUtil.isNotNull(seqRegistryBusiEntity)){
                caffeineCacheService.put(name,seqRegistryBusiEntity);
            }
        }else{
            seqRegistryBusiEntity  = (SeqRegistryBusiEntity)seqRegistryBusiValue;
        }
        return seqRegistryBusiEntity;
    }
}
